/**************************************************************
 * @file     bsp_key.c
 * @brief    实现按键驱动队列发送消息，支持按键单击，长按检测
 * @author   Ruilist
 * @date     2025-07-27
 * @version  V1.0.0
 * @copyright Copyright (c) 2025
 *
 * @note     1 tab = 4 space
 *
 * @par 日志:
 * - V1.0.0 2025-07-27 Ruilist
 *   实现按键驱动队列发送消息
 **************************************************************/

#include "bsp_key.h"

osThreadId_t key_TaskHandle;

const osThreadAttr_t key_Task_attributes = {
    .name       = "key_Task",
    .stack_size = 128 * 4,
    .priority   = (osPriority_t)osPriorityNormal,
};

QueueHandle_t key_queue;

/**
 * @brief   按键任务
 *
 * @param   *argument    任务默认参数
 *
 * @return  空
 *
 */
void key_task_func( void *argument )
{
    key_status_t       ket_ret     = KEY_OK;
    key_press_status_t key_statues = KEY_NOT_PRESSED;
    key_queue                      = xQueueCreate( 10, sizeof( uint32_t ) );

    if ( NULL == key_queue )
    {
        printf( "key_queue created failed \r\n" );
    }
    else
    {
        printf( "key_queue created successfully \r\n" );
    }
    for ( ;; )
    {
        printf( "start key_task_func\r\n" );
        ket_ret = key_long_short_press( &key_statues, 1000 );
        if ( KEY_OK == ket_ret )
        {
            if ( KEY_SHORT_PRESSED == key_statues )
            {
                printf( "short pressed at [%d] tick \r\n", HAL_GetTick() );
                if ( pdTRUE == xQueueSendToFront( key_queue, &key_statues, 0 ) )
                {
                    printf( "short pressed send successfully at [%d] tick \r\n", HAL_GetTick() );
                }
            }
            if ( KEY_LONG_PRESSED == key_statues )
            {
                printf( "long pressed at [%d] tick \r\n", HAL_GetTick() );
                if ( pdTRUE == xQueueSendToFront( key_queue, &key_statues, 0 ) )
                {
                    printf( "long pressed send successfully at [%d] tick \r\n", HAL_GetTick() );
                }
            }
        }
         osDelay( 100 );
    }
}

/**
 * @brief   按键状态轮询
 *
 * @param   *key_value    用作按键状态传参
 *
 * @return  函数状态 key_status_t
 *
 */

key_status_t key_scan( key_press_status_t *key_value )
{
    key_press_status_t key_status_value = KEY_NOT_PRESSED;

    if ( GPIO_PIN_RESET == HAL_GPIO_ReadPin( KEY_GPIO_Port, KEY_Pin ) )
    {
        key_status_value = KEY_PRESSED;
        *key_value       = key_status_value;
        return KEY_OK;
    }

    *key_value = key_status_value;

    return KEY_ERRORTIMEOUT;  // 始终没有按键被按下，返回超时
}

/**
 * @brief   检测按键单击，长按状态
 *
 * @param   *key_value    按键触发状态传参
 * @param   threshold_time    单击检测时间阈值
 *
 * @return  函数状态 key_status_t
 *
 */
key_status_t key_long_short_press( key_press_status_t *key_value, uint32_t threshold_time )
{
    key_status_t       ret_key_status = KEY_OK;
    key_press_status_t temp_key_value = KEY_NOT_PRESSED;
    uint32_t           time_counter   = 0;

    ret_key_status = key_scan( &temp_key_value );

    if ( KEY_OK == ret_key_status )
    {
        if ( KEY_PRESSED == temp_key_value )
        {
            time_counter = HAL_GetTick();
            while ( HAL_GetTick() < time_counter + threshold_time )
                ;
            ret_key_status = key_scan( &temp_key_value );
            if ( KEY_NOT_PRESSED == temp_key_value )
            {
                *key_value = KEY_SHORT_PRESSED;
                return KEY_OK;
            }
            else
            {
                *key_value = KEY_LONG_PRESSED;
                while ( KEY_OK == key_scan( &temp_key_value ) )
                    ;
                return KEY_OK;
            }
        }
    }
    return ret_key_status;
}
